package com.lcredu.springboot;

import com.lcredu.springboot.config.BeanConfig;
import com.lcredu.springboot.entity.Cat;
import com.lcredu.springboot.entity.Dog;
import com.lcredu.springboot.entity.Monster;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author 黎长容
 * @date 2025-08-08 22:53
 */

/**
 * Spring Boot应用程序启动类注解
 * <p>
 * 该注解用于标识一个Spring Boot应用程序的主配置类，它是一个组合注解，
 * 包含了@Configuration、@EnableAutoConfiguration和@ComponentScan的功能
 * <p>
 * scanBasePackages 指定组件扫描的基础包路径数组，Spring会扫描这些包及其子包下的组件
 * 包含: "com.lcredu.springboot" - 主要业务包路径
 * "com.lcredu.text.controller" - 控制器包路径
 *
 * @return 无返回值
 */
@SpringBootApplication(scanBasePackages = {"com.lcredu.springboot", "com.lcredu.text.controller"})

public class MainApp {
    public static void main(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        int i = 1;
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println("第" + i + "个beanName = " + beanDefinitionName);
            i++;
        }

//        Monster monster = ioc.getBean(Monster.class);
//        System.out.println(monster);

        //传统spring方式获取springBean对象
//        ApplicationContext ac = new ClassPathXmlApplicationContext("beans01.xml");
//        Monster monster = ac.getBean("monster01", Monster.class);
//        System.out.println("monster01=" + monster);

        //springboot获取bean
        // 检查 Bean 是否被正确注册
        // 检查 Bean 的作用域
//        BeanDefinition beanDefinition = ioc.getBeanFactory().getBeanDefinition("monster01");
//        System.out.println("Bean scope: " + beanDefinition.getScope());

        // 测试获取 Bean
//        Monster monster1 = ioc.getBean("monster01", Monster.class);
//        Monster monster2 = ioc.getBean("monster01", Monster.class);
//        System.out.println(monster1 + "=" + monster1.hashCode());
//        System.out.println(monster2 + "=" + monster2.hashCode());


        //配置类本身也是组件， 因此也可以获取
//        BeanConfig beanConfig = ioc.getBean(BeanConfig.class);
//        Monster monster1 = beanConfig.monster01();
//        Monster monster2 = beanConfig.monster01();
//        System.out.println(monster1 + "=" + monster1.hashCode());
//        System.out.println(monster2 + "=" + monster2.hashCode());


        //----测试@Import注入bean----start
//        Dog dog = ioc.getBean(Dog.class);
//        Cat cat = ioc.getBean(Cat.class);
//        System.out.println(dog);
//        System.out.println(cat);

        //----测试@Import注入bean----end


        //----测试 @ConditionalOnBean----start
//        Cat cat = ioc.getBean(Cat.class);
//        System.out.println(cat);
//        Dog dog = ioc.getBean(Dog.class);
//        System.out.println(dog);

        //----测试 @ConditionalOnBean----end


        //----测试 @ImportResource----start
        Monster monster = ioc.getBean("monster01", Monster.class);
        System.out.println(monster);

        boolean b = ioc.containsBean("monster03");
        System.out.println("狐狸精在吗" + b);

        //----测试 @ImportResource----end
    }
}
